package middleware

import (
	"freely/bin/comm"
	"freely/bin/utils"
	"freely/src/constant"
	"freely/src/methods"
	"net/http"

	"github.com/gin-gonic/gin"
)

/**
 * 鉴权，检查是否拥有访问权限
 */
func TokenAuth(ctx *gin.Context, ignoreList map[string]bool) {
	fromTo := ctx.GetHeader(constant.AuthFromTo)
	if fromTo == "" {
		ctx.String(http.StatusNotFound, constant.ErrNotFound.Error())
		ctx.Abort()
		return
	}

	ctx.Set(constant.AuthFromTo, fromTo)

	path := ctx.Request.URL.Path

	// 不需要token的路由直接跳过
	if ignoreList[path] {
		ctx.Next()
		return
	}

	auth := ctx.GetHeader(constant.Author)
	if auth == "" {
		ctx.String(http.StatusForbidden, constant.ErrToken.Error())
		ctx.Abort()
		return
	}

	jwt, err := methods.TokenParse(auth)
	if err != nil {
		ctx.String(http.StatusUnauthorized, err.Error())
		ctx.Abort()
		return
	}

	tokenHash := utils.StrToHash(auth)
	res, err := comm.RedisCli.Get(comm.AppCtx, tokenHash).Result()
	if err != nil || res == "" {
		// 表示用户已经退出登录
		comm.RedisCli.SRem(comm.AppCtx, constant.RedisOnlineUsers, jwt.UserID)
		ctx.String(http.StatusUnauthorized, constant.ErrTokenExpired.Error())
		ctx.Abort()
		return
	}

	// 设置当前访问用户信息
	ctx.Set(constant.AuthUserID, jwt.UserID)
	ctx.Set(constant.AuthUsername, jwt.Username)
	ctx.Set(constant.AuthRoleID, jwt.RoleID)
	ctx.Set(constant.AuthRole, jwt.Role)

	ctx.Next()
}
